package com.linxin.ai_automates_periodontal_treatment_system.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linxin.ai_automates_periodontal_treatment_system.common.Result;
import com.linxin.ai_automates_periodontal_treatment_system.entity.Doctor;
import com.linxin.ai_automates_periodontal_treatment_system.entity.DoctorLog;
import com.linxin.ai_automates_periodontal_treatment_system.entity.LoginLog;
import com.linxin.ai_automates_periodontal_treatment_system.service.DoctorLogService;
import com.linxin.ai_automates_periodontal_treatment_system.service.DoctorService;
import com.linxin.ai_automates_periodontal_treatment_system.service.LoginLogService;
import com.linxin.ai_automates_periodontal_treatment_system.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/doctor")
public class DoctorController {

    @Value("${image.doctor-image-path}")
    private String doctorImagePath;

    @Autowired
    private DoctorService doctorService;

    @Autowired
    private LoginLogService loginLogService;

    @Autowired
    private DoctorLogService doctorLogService;

    /**
     * 医生注册
     *
     * @param doctor
     * @return
     */
    @PostMapping("/register")
    public Result<Doctor> register(@RequestBody Doctor doctor) {
        log.info("doctor register request: " + doctor);
        // 1. 判断用户是否已经存在
        LambdaQueryWrapper<Doctor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Doctor::getAccount, doctor.getAccount());
        Doctor existDoctor = doctorService.getOne(wrapper);
        if (existDoctor != null) {
            return Result.error("该账号已存在");
        }

        // 2. 用户不存在，进行注册
        // 设置创建时间
        doctor.setCreateTime(LocalDateTime.now());
        // 设置更新时间
        doctor.setUpdateTime(LocalDateTime.now());

        // 一致则进行注册
        doctorService.save(doctor);

        return Result.success(doctor);
    }


    /**
     * 医生登录
     *
     * @param doctor
     * @return
     */
    @PostMapping("/login")
    public Result<Map<String, String>> login(@RequestBody Doctor doctor) {
        // 1. 判断用户是否存在
        LambdaQueryWrapper<Doctor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Doctor::getAccount, doctor.getAccount());
        Doctor existDoctor = doctorService.getOne(wrapper);
        if (existDoctor == null) {
            return Result.error("账户或密码错误");
        }

        // 2. 用户存在，进行登录
        // 先判断密码是否正确
        if (!existDoctor.getPassword().equals(doctor.getPassword())) {
            return Result.error("用户名或密码错误");
        }
        // 生成token
        String token = JwtUtil.generateToken(doctor);
        //  log.info("generate token: {}", token);
        // 将token返回给前端

        // 记录登录日志
        LoginLog loginLog = new LoginLog();
        loginLog.setDoctorId(existDoctor.getId());
        loginLog.setCreateTime(LocalDateTime.now());
        loginLog.setUpdateTime(LocalDateTime.now());
        loginLogService.save(loginLog);
        return Result.success(Map.of("token", token));
    }

    /**
     * 获取医生信息
     *
     * @param request
     * @return
     */
    @GetMapping("/info")
    public Result<Doctor> info(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null) {
            return Result.error("请先登录");
        }
        String account = JwtUtil.getAccountFromToken(token);
        Doctor doctor = doctorService.getOne(new LambdaQueryWrapper<Doctor>().eq(Doctor::getAccount, account));
        if (doctor == null) {
            return Result.error("用户不存在");
        }

        // 获取在数据库的头像文件名
        String picture = doctor.getPicture();
        // 在本地文件系统中查找头像文件
        String doctorImagePath = this.doctorImagePath + picture;
        if (FileUtil.exist(doctorImagePath) && !picture.isEmpty()) {
            // 头像文件存在，将头像文件内容转换为base64编码
            byte[] imageBytes = FileUtil.readBytes(doctorImagePath);
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            // 添加data:image/png;base64,前缀
            base64Image = "data:image/png;base64," + base64Image;
            doctor.setPicture(base64Image);
        }

        return Result.success(doctor);
    }

    /**
     * 删除医生信息
     *
     * @param doctor
     * @return
     */
    @PostMapping("/deleteDoctor")
    public Result<String> delete(@RequestBody Doctor doctor) {
        // 根据doctorId删除doctor
        doctorService.removeById(doctor.getId());
        // 删除对应的头像文件
        String picture = doctor.getPicture();
        if (picture != null && !picture.isEmpty()) {
            String doctorImagePath = this.doctorImagePath + picture;
            if (FileUtil.exist(doctorImagePath)) {
                FileUtil.del(doctorImagePath);
            }
        }
        return Result.success("删除成功");

    }

    /**
     * 更新医生信息
     *
     * @param doctor
     * @param request
     * @return
     */
    @PutMapping("/updateInfo")
    public Result<String> update(@RequestBody Doctor doctor, HttpServletRequest request) {
        // 1. 获取attribute中的doctorId
        Integer doctorId = (Integer) request.getAttribute("doctorId");

        // 3. 根据doctorId在数据库中查找doctor
        Doctor existDoctor = doctorService.getById(doctorId);

        // 4. 判断doctor是否存在
        if (existDoctor == null) {
            return Result.error("用户不存在");
        }

        // 5. 更新doctor信息
        existDoctor.setName(doctor.getName());
        existDoctor.setGender(doctor.getGender());
        existDoctor.setPhone(doctor.getPhone());
        existDoctor.setClassifyId(doctor.getClassifyId());
        existDoctor.setProfile(doctor.getProfile());
        existDoctor.setProfession(doctor.getProfession());

        // 6. 更新数据库
        doctorService.updateById(existDoctor);

        // 更新医生日志
        DoctorLog doctorLog = new DoctorLog();
        doctorLog.setDoctorId(doctorId);
        // 设置操作类型为 更新
        doctorLog.setType("更新");
        // 设置描述
        doctorLog.setLogDec("更新医生信息");
        // 设置创建时间
        doctorLog.setCreateTime(LocalDateTime.now());
        // 设置更新时间
        doctorLog.setUpdateTime(LocalDateTime.now());
        // 保存日志
        doctorLogService.save(doctorLog);

        // 7. 返回成功信息
        return Result.success("更新成功");
    }

    /**
     * 上传医生图片
     *
     * @param requestBody
     * @param request
     * @return
     */
    @PatchMapping("/uploadImage")
    public Result<String> uploadAvatar(@RequestBody Map<String, String> requestBody, HttpServletRequest request) {
        String base64Avatar = requestBody.get("picture");

        try {
            // 移除可能的 data URI scheme 前缀
            if (base64Avatar.startsWith("data:image/png;base64,")) {
                base64Avatar = base64Avatar.substring("data:image/png;base64,".length());
            }

            // 填充base64字符串长度为4的倍数
            int padding = (4 - base64Avatar.length() % 4) % 4;
            base64Avatar = base64Avatar + "=".repeat(padding);

            // 将base64编码的图片数据转换为字节数组
            byte[] decodedAvatar = Base64.getDecoder().decode(base64Avatar);
            // log.info("decodedAvatar length: {}", decodedAvatar.length);

            String uniqueFileName = UUID.randomUUID().toString() + ".jpg";
            // 保存头像图片到文件
            FileUtil.writeBytes(decodedAvatar, doctorImagePath + uniqueFileName);

            // 获取用户id
            Integer doctorId = (Integer) request.getAttribute("doctorId");

            // 根据id查询数据库, 将头像文件名更新到数据库
            Doctor doctor = doctorService.getById(doctorId);

            // 删除原来的头像文件
            String oldAvatar = doctor.getPicture();
            if (oldAvatar != null && !oldAvatar.isEmpty()) {
                String oldAvatarFilePath = doctorImagePath + oldAvatar;
                if (FileUtil.exist(oldAvatarFilePath)) {
                    FileUtil.del(oldAvatarFilePath);
                }
            }

            doctor.setPicture(uniqueFileName);
            doctorService.updateById(doctor);

            return Result.success("头像上传成功");
        } catch (IllegalArgumentException e) {
            // log.error("Failed to decode base64 avatar: {}", e.getMessage());
            Result.error("头像上传失败, 请检查图片格式");
        } catch (Exception e) {
            // log.error("Failed to upload avatar: {}", e.getMessage());
            Result.error("头像上传失败, 请检查服务器配置");
        }
        return Result.error("头像上传失败, 请检查图片格式");
    }

    /**
     * 判断医生是否已完成基本信息的填写
     *
     * @param request
     * @return
     */
    @GetMapping("/isComplete")
    public Result<Map<String, Integer>> isComplete(HttpServletRequest request) {
        // 获取用户id
        Integer doctorId = (Integer) request.getAttribute("doctorId");

        // 根据id查询数据库, 判断是否已完成注册
        Doctor doctor = doctorService.getById(doctorId);

        // 判断doctor的name、gender、phone、picture、occupation、profile、profession是否都不为空, 且不为null
        // gender为char类型
        if (doctor != null && doctor.getName() != null && doctor.getGender() != null && doctor.getPhone() != null && doctor.getPicture() != null && doctor.getClassifyId() != null && doctor.getProfile() != null && doctor.getProfession() != null) {
            return Result.success(Map.of("isComplete", 1));
        }
        return Result.success(Map.of("isComplete", 0));
    }


    // 获取医生列表
    @GetMapping("/list")
    public Result<Page<Doctor>> list(
            @RequestParam(value = "pageNum", required = true) Integer pageNum,
            @RequestParam(value = "pageSize", required = true) Integer pageSize,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "gender", required = false) Integer gender,
            @RequestParam(value = "classifyId", required = false) Integer classifyId,
            HttpServletRequest request
    ) {

        // 1. 创建分页查询对象
        Page<Doctor> page = new Page<>(pageNum, pageSize);
        // 获取doctorId
        Integer doctorId = (Integer) request.getAttribute("doctorId");


        // 2. 创建查询条件
        LambdaQueryWrapper<Doctor> wrapper = new LambdaQueryWrapper<>();
        if (name != null && !name.isEmpty()) {
            wrapper.like(Doctor::getName, name);
        }
        if (classifyId != null) {
            wrapper.eq(Doctor::getClassifyId, classifyId);
        }
        if (gender != null) {
            wrapper.eq(Doctor::getGender, gender);
        }

        // 根据id倒序
        wrapper.orderByDesc(Doctor::getCreateTime).orderByDesc(Doctor::getId);
        // 排除dutyDoctorId为当前doctorId的doctor
        wrapper.ne(Doctor::getId, doctorId);

        // 3. 执行查询
        doctorService.page(page, wrapper);

        return Result.success(page);
    }

    @PutMapping("/updateOtherInfo")
    public Result<String> updateOtherInfo(@RequestBody Doctor doctor) {
        // 根据id更新其他信息
        doctorService.updateById(doctor);
        return Result.success("更新成功");
    }

}
